package com.china.zhuoyue.ui.base

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
import by.kirich1409.viewbindingdelegate.viewBinding
import com.china.zhuoyue.ui.listener.OnStartActivityListener
import com.china.zhuoyue.ui.utils.Logger
import java.lang.reflect.ParameterizedType

/**
 * Created by vicky on 2016/11/7.
 */
open class BaseFragment<VB : ViewBinding> : Fragment(), OnStartActivityListener,
    View.OnClickListener {
    protected val vb: VB by viewBinding(::loadViewBinding)
    protected lateinit var mThis: BaseFragment<VB>
    protected var mView: View? = null
    protected var mSavedInstanceState: Bundle? = null
    private val dispatcher by lazy { requireActivity().onBackPressedDispatcher }
    private val callback: OnBackPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            onBackPressed()
        }
    }
    private var mActivityForResult: ActivityForResult? = null
    private var mIsNeedResultOk: Boolean? = null
    private var mRequestMultiplePermissions: RequestMultiplePermissions? = null
    private val mStartActivityForResultLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
            if (mIsNeedResultOk == true) {
                if (activityResult.resultCode == AppCompatActivity.RESULT_OK)
                    mActivityForResult?.invoke(activityResult)
            } else {
                mActivityForResult?.invoke(activityResult)
            }
        }
    private val mRequestMultiplePermissionsLauncher =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { activityResult ->
            mRequestMultiplePermissions?.invoke(activityResult)
            lifecycleScope
        }

    private fun loadViewBinding(fragment: Fragment): VB {
        val clz =
            (this::class.java.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<ViewBinding>
        val method = clz.getDeclaredMethod("inflate", LayoutInflater::class.java)
        return method.invoke(null, layoutInflater) as VB
    }

    open fun loadView(load: VB.() -> Unit) = vb.also(load)

    fun onBackPressed() {
        callback.isEnabled = false
        dispatcher.onBackPressed()
    }

    fun hasExtras(): Boolean {
        return arguments != null
    }

    override fun getView(): View? {
        return mView
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mThis = this
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mView = vb.root
        try {
            mSavedInstanceState = savedInstanceState
            init(mView, savedInstanceState)
            initView(mView, savedInstanceState)
            initData(mView, savedInstanceState)
        } catch (e: Exception) {
            Logger.e(e)
        }
        return mView
    }

    open fun init(rootView: View?, savedInstanceState: Bundle?) {}
    open fun initView(rootView: View?, savedInstanceState: Bundle?) {}
    open fun initData(rootView: View?, savedInstanceState: Bundle?) {}

    override fun onClick(v: View?) {

    }

    fun bindViewClick(vararg views: View) = com.china.zhuoyue.ui.ext.bindViewClick(this, *views)
    open fun launchStartActivityForResult(
        clazz: Class<*>,
        options: Bundle? = null,
        isNeedResultOk: Boolean = true,
        activityForResult: ActivityForResult? = null
    ) {
        val intent = Intent(context, clazz)
        options?.let { intent.putExtras(it) }
        mActivityForResult = activityForResult
        mIsNeedResultOk = isNeedResultOk
        mStartActivityForResultLauncher.launch(intent)
    }

    open fun launchRequestMultiplePermissions(
        permissions: Array<String>,
        requestMultiplePermissions: RequestMultiplePermissions? = null
    ) {
        mRequestMultiplePermissions = requestMultiplePermissions
        mRequestMultiplePermissionsLauncher.launch(permissions)
    }

    override fun goActicity(clazz: Class<*>, bundle: Bundle?, requestCode: Int?) {
        val intent = Intent(context, clazz)
        bundle?.let { intent.putExtras(it) }
        if (requestCode != null) {
            startActivityForResult(intent, requestCode)
        } else {
            startActivity(intent)
        }
    }

    override fun goActicityFinish(clazz: Class<*>, bundle: Bundle?, requestCode: Int?) {
        goActicity(clazz, bundle, requestCode)
        activity?.finish()
    }

}